<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>Freetype OpenGL: demo-benchmark.c</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="content"><!-- do not remove this div! -->

<div id="top"><!-- do not remove this div! -->

  
  <div id="titlearea">
    
    <div id="projectname">Freetype OpenGL</div>
    
    
    <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
    
  </div>
  

<!--

<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Freetype OpenGL
   &#160;<span id="projectnumber">0.1</span>
   </div>
   <div id="projectbrief">A high quality OpenGL text rendering engine for C</div>
  </td>
  
  
  
   
  
 </tr>
 </tbody>
</table>
</div>
-->


<!-- Generated by Doxygen 1.8.0 -->
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">demo-benchmark.c</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><span class="comment">/* ============================================================================</span>
<span class="comment"> * Freetype GL - A C OpenGL Freetype engine</span>
<span class="comment"> * Platform:    Any</span>
<span class="comment"> * WWW:         http://code.google.com/p/freetype-gl/</span>
<span class="comment"> * ----------------------------------------------------------------------------</span>
<span class="comment"> * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.</span>
<span class="comment"> *</span>
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<span class="comment"> * modification, are permitted provided that the following conditions are met:</span>
<span class="comment"> *</span>
<span class="comment"> *  1. Redistributions of source code must retain the above copyright notice,</span>
<span class="comment"> *     this list of conditions and the following disclaimer.</span>
<span class="comment"> *</span>
<span class="comment"> *  2. Redistributions in binary form must reproduce the above copyright</span>
<span class="comment"> *     notice, this list of conditions and the following disclaimer in the</span>
<span class="comment"> *     documentation and/or other materials provided with the distribution.</span>
<span class="comment"> *</span>
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER &#39;&#39;AS IS&#39;&#39; AND ANY EXPRESS OR</span>
<span class="comment"> * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF</span>
<span class="comment"> * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO</span>
<span class="comment"> * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,</span>
<span class="comment"> * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span>
<span class="comment"> * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span>
<span class="comment"> * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span>
<span class="comment"> * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF</span>
<span class="comment"> * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="comment"> *</span>
<span class="comment"> * The views and conclusions contained in the software and documentation are</span>
<span class="comment"> * those of the authors and should not be interpreted as representing official</span>
<span class="comment"> * policies, either expressed or implied, of Nicolas P. Rougier.</span>
<span class="comment"> * ============================================================================</span>
<span class="comment"> */</span>
<span class="preprocessor">#include &quot;freetype-gl.h&quot;</span>
<span class="preprocessor">#include &quot;<a class="code" href="vertex-buffer_8h.html">vertex-buffer.h</a>&quot;</span>


<span class="comment">// ------------------------------------------------------- typedef &amp; struct ---</span>
<span class="keyword">typedef</span> <span class="keyword">struct </span>{
    <span class="keywordtype">float</span> x, y, z;    <span class="comment">// position</span>
    <span class="keywordtype">float</span> s, t;       <span class="comment">// texture</span>
    <span class="keywordtype">float</span> r, g, b, a; <span class="comment">// color</span>
} vertex_t;


<span class="comment">// ------------------------------------------------------- global variables ---</span>
<a name="_a0"></a><a class="code" href="structtexture__atlas__t.html" title="A texture atlas is used to pack several small regions into a single texture.">texture_atlas_t</a> * atlas;
<a name="_a1"></a><a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font;
<a name="_a2"></a><a class="code" href="structvertex__buffer__t.html" title="Generic vertex buffer.">vertex_buffer_t</a> * buffer;
<span class="keywordtype">wchar_t</span> *text =
    L<span class="stringliteral">&quot;A Quick Brown Fox Jumps Over The Lazy Dog 0123456789 &quot;</span>
    L<span class="stringliteral">&quot;A Quick Brown Fox Jumps Over The Lazy Dog 0123456789 &quot;</span>;
<span class="keywordtype">int</span> line_count = 42;



<span class="comment">// --------------------------------------------------------------- add_text ---</span>
<span class="keywordtype">void</span> add_text( <a class="code" href="structvertex__buffer__t.html" title="Generic vertex buffer.">vertex_buffer_t</a> * buffer, <a class="code" href="structtexture__font__t.html" title="Texture font structure.">texture_font_t</a> * font,
               <span class="keywordtype">wchar_t</span> * text, <a name="_a3"></a><a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> * color, <a name="_a4"></a><a class="code" href="unionvec2.html" title="Tuple of 2 floats.">vec2</a> * pen )
{
    <span class="keywordtype">size_t</span> i;
    <span class="keywordtype">float</span> r = color-&gt;<a name="a5"></a><a class="code" href="unionvec4.html#a217cd1d02c6d3ca6892f0df6542212f7" title="Alias for first component.">red</a>, g = color-&gt;<a name="a6"></a><a class="code" href="unionvec4.html#ac5b751220d5788595e9409ef2a40faf3" title="Alias fo second component.">green</a>, b = color-&gt;<a name="a7"></a><a class="code" href="unionvec4.html#ab68efbfaadd2ce9a9fae04cbbd3db839" title="Alias fo third component.">blue</a>, a = color-&gt;<a name="a8"></a><a class="code" href="unionvec4.html#ad5ffee1a120a0856cdab9c03882a7401" title="Alias fo fourth component.">alpha</a>;
    <span class="keywordflow">for</span>( i=0; i&lt;wcslen(text); ++i )
    {
        <a name="_a9"></a><a class="code" href="structtexture__glyph__t.html" title="A structure that describe a glyph.">texture_glyph_t</a> *glyph = <a name="a10"></a><a class="code" href="group__texture-font.html#ga06e988448ef6e118aa6e273df5892937" title="Request a new glyph from the font.">texture_font_get_glyph</a>( font, text[i] );
        <span class="keywordflow">if</span>( glyph != NULL )
        {
            <span class="keywordtype">int</span> kerning = 0;
            <span class="keywordflow">if</span>( i &gt; 0)
            {
                kerning = <a name="a11"></a><a class="code" href="group__texture-font.html#ga77d1adb569e7eaa4aaf776dc28415c66" title="Get the kerning between two horizontal glyphs.">texture_glyph_get_kerning</a>( glyph, text[i-1] );
            }
            pen-&gt;<a name="a12"></a><a class="code" href="unionvec2.html#a002d3519d48fe3cd79729b5b0ded74bf" title="Alias for first component.">x</a> += kerning;
            <span class="keywordtype">int</span> x0  = (int)( pen-&gt;<a class="code" href="unionvec2.html#a002d3519d48fe3cd79729b5b0ded74bf" title="Alias for first component.">x</a> + glyph-&gt;<a name="a13"></a><a class="code" href="structtexture__glyph__t.html#a1f267cdba6bd1aff244ff72792ab1a38" title="Glyph&#39;s left bearing expressed in integer pixels.">offset_x</a> );
            <span class="keywordtype">int</span> y0  = (int)( pen-&gt;<a name="a14"></a><a class="code" href="unionvec2.html#a6d28b12b511da692550fc9d37b4e9b1d" title="Alias for second component.">y</a> + glyph-&gt;<a name="a15"></a><a class="code" href="structtexture__glyph__t.html#aeacd07f592dfa953f26b2e5c1863a814" title="Glyphs&#39;s top bearing expressed in integer pixels.">offset_y</a> );
            <span class="keywordtype">int</span> x1  = (int)( x0 + glyph-&gt;<a name="a16"></a><a class="code" href="structtexture__glyph__t.html#a51379921bd46b454fc56b7d28381af03" title="Glyph&#39;s width in pixels.">width</a> );
            <span class="keywordtype">int</span> y1  = (int)( y0 - glyph-&gt;<a name="a17"></a><a class="code" href="structtexture__glyph__t.html#a7a0e2fc48006cf6815e5b1e7dae8d386" title="Glyph&#39;s height in pixels.">height</a> );
            <span class="keywordtype">float</span> s0 = glyph-&gt;<a name="a18"></a><a class="code" href="structtexture__glyph__t.html#adcfb6e5a1b583f96c96d87b006667f2b" title="First normalized texture coordinate (x) of top-left corner.">s0</a>;
            <span class="keywordtype">float</span> t0 = glyph-&gt;<a name="a19"></a><a class="code" href="structtexture__glyph__t.html#ab2fec7dd584f5cfaf14c3b8a807d5e70" title="Second normalized texture coordinate (y) of top-left corner.">t0</a>;
            <span class="keywordtype">float</span> s1 = glyph-&gt;<a name="a20"></a><a class="code" href="structtexture__glyph__t.html#a3849b83a8bb51a6fc32ce77b485d9e95" title="First normalized texture coordinate (x) of bottom-right corner.">s1</a>;
            <span class="keywordtype">float</span> t1 = glyph-&gt;<a name="a21"></a><a class="code" href="structtexture__glyph__t.html#aee3ba35a29e1646df9cfaca6c0db3488" title="Second normalized texture coordinate (y) of bottom-right corner.">t1</a>;
            GLuint index = buffer-&gt;<a name="a22"></a><a class="code" href="structvertex__buffer__t.html#a54efd077fb2990b3679d060baaa021ec" title="Vector of vertices.">vertices</a>-&gt;<a name="a23"></a><a class="code" href="structvector__t.html#a7ec97862387465722f8f08f8f8f69371" title="Number of items.">size</a>;
            GLuint indices[] = {index, index+1, index+2,
                                index, index+2, index+3};
            vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                                    { x0,y1,0,  s0,t1,  r,g,b,a },
                                    { x1,y1,0,  s1,t1,  r,g,b,a },
                                    { x1,y0,0,  s1,t0,  r,g,b,a } };
            vertex_buffer_push_back_indices( buffer, indices, 6 );
            vertex_buffer_push_back_vertices( buffer, vertices, 4 );
            pen-&gt;<a class="code" href="unionvec2.html#a002d3519d48fe3cd79729b5b0ded74bf" title="Alias for first component.">x</a> += glyph-&gt;<a name="a24"></a><a class="code" href="structtexture__glyph__t.html#aba3ece1130e9d96562a5c2ec3e60da4c" title="For horizontal text layouts, this is the horizontal distance (in fractional pixels) used to increment...">advance_x</a>;
        }
    }
}


<span class="comment">// ---------------------------------------------------------------- display ---</span>
<span class="keywordtype">void</span> display( <span class="keywordtype">void</span> )
{
    <span class="keyword">static</span> <span class="keywordtype">int</span> frame=0, time, timebase=0;
    <span class="keyword">static</span> <span class="keywordtype">int</span> count = 0;

    <span class="keywordflow">if</span>( count == 0 &amp;&amp; frame == 0 )
    {
        printf(
            <span class="stringliteral">&quot;Computing FPS with text generation and rendering at each frame...\n&quot;</span> );
        printf(
            <span class="stringliteral">&quot;Number of glyphs: %d\n&quot;</span>, (<span class="keywordtype">int</span>)wcslen(text)*line_count );
    }

    frame++;
    time = glutGet( GLUT_ELAPSED_TIME );

    <span class="keywordflow">if</span>( time-timebase &gt; (2500) )
    {
        printf( <span class="stringliteral">&quot;FPS : %.2f (%d frames in %.2f second, %.1f glyph/second)\n&quot;</span>,
                frame*1000.0/(time-timebase), frame, (time-timebase)/1000.0,
                frame*1000.0/(time-timebase) * wcslen(text)*line_count );
        timebase = time;
        frame = 0;
        ++count;
        <span class="keywordflow">if</span>( count == 5 )
        {
            printf( <span class="stringliteral">&quot;\nComputing FPS with text rendering at each frame...\n&quot;</span> );
            printf( <span class="stringliteral">&quot;Number of glyphs: %d\n&quot;</span>, (<span class="keywordtype">int</span>)wcslen(text)*line_count );
        }
        <span class="keywordflow">if</span>( count &gt; 9 )
        {
            exit( EXIT_SUCCESS );
        }
    }
    <span class="keywordflow">if</span>( count &lt; 5 )
    {
        <span class="keywordtype">size_t</span> i;
        <a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> color = {{0,0,0,1}};
        <a class="code" href="unionvec2.html" title="Tuple of 2 floats.">vec2</a> pen = {{0,0}};
        <a name="a25"></a><a class="code" href="group__vertex-buffer.html#ga5a1c907e3e66b12be0c142e6d03acdaf" title="Clear all items.">vertex_buffer_clear</a>( buffer );

        pen.<a class="code" href="unionvec2.html#a6d28b12b511da692550fc9d37b4e9b1d" title="Alias for second component.">y</a> = -font-&gt;<a name="a26"></a><a class="code" href="structtexture__font__t.html#af310fa623576a8436bff9354f9a5c048" title="The descender is the vertical distance from the horizontal baseline to the lowest &#39;character&#39; coordin...">descender</a>;
        <span class="keywordflow">for</span>( i=0; i&lt;line_count; ++i )
        {
            pen.<a class="code" href="unionvec2.html#a002d3519d48fe3cd79729b5b0ded74bf" title="Alias for first component.">x</a> = 10.0;
            add_text( buffer, font, text, &amp;color, &amp;pen );
            pen.<a class="code" href="unionvec2.html#a6d28b12b511da692550fc9d37b4e9b1d" title="Alias for second component.">y</a> += font-&gt;<a name="a27"></a><a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a> - font-&gt;<a name="a28"></a><a class="code" href="structtexture__font__t.html#af40d45f0616a523d97206e6e0e72f421" title="This field is the distance that must be placed between two lines of text.">linegap</a>;
        }
    }
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor4f( 0,0,0,1 );
    glBindTexture( GL_TEXTURE_2D, atlas-&gt;<a name="a29"></a><a class="code" href="structtexture__atlas__t.html#a03e72bd01b6e5e97c0cc032d22c11c45" title="Texture identity (OpenGL)">id</a> );
    <a name="a30"></a><a class="code" href="group__vertex-buffer.html#ga48df5bafd9315aabfb7f14bedb778c16" title="Render vertex buffer.">vertex_buffer_render</a>( buffer, GL_TRIANGLES, <span class="stringliteral">&quot;vtc&quot;</span> );
    glutSwapBuffers( );
}


<span class="comment">// ---------------------------------------------------------------- reshape ---</span>
<span class="keywordtype">void</span> reshape( <span class="keywordtype">int</span> width, <span class="keywordtype">int</span> height )
{
    glViewport(0, 0, width, height);
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    glOrtho(0, width, 0, height, -1, 1);
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );
}


<span class="comment">// --------------------------------------------------------------- keyboard ---</span>
<span class="keywordtype">void</span> keyboard( <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key, <span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y )
{
    <span class="keywordflow">if</span> ( key == 27 )
    {
        exit( EXIT_SUCCESS );
    }
}


<span class="comment">// ------------------------------------------------------------------- idle ---</span>
<span class="keywordtype">void</span> idle( <span class="keywordtype">void</span> )
{
    glutPostRedisplay();
}


<span class="comment">// ------------------------------------------------------------------- main ---</span>
<span class="keywordtype">int</span> main( <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv )
{
    <span class="keywordtype">size_t</span> i;
    <a class="code" href="unionvec4.html" title="Tuple of 4 floats.">vec4</a> color = {{0,0,0,1}};
    <a class="code" href="unionvec2.html" title="Tuple of 2 floats.">vec2</a> pen = {{0,0}};

    glutInit( &amp;argc, argv );
    glutInitWindowSize( 800, 600 );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( <span class="stringliteral">&quot;Freetype OpenGL benchmark&quot;</span> );
    glutReshapeFunc( reshape );
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );
    glutIdleFunc( idle );

    atlas  = <a name="a31"></a><a class="code" href="group__texture-atlas.html#ga7769be70f630e0a8a8b320525a07382d" title="Creates a new empty texture atlas.">texture_atlas_new</a>( 512, 512, 1 );
    font = <a name="a32"></a><a class="code" href="group__texture-font.html#ga904424e7b0e2be14b694599b5c483e64" title="This function creates a new texture font from given filename and size.">texture_font_new</a>( atlas, <span class="stringliteral">&quot;fonts/VeraMono.ttf&quot;</span>, 12 );
    buffer = <a name="a33"></a><a class="code" href="group__vertex-buffer.html#ga309c1129a1028f251fe6e6c3c1534a42" title="Creates an empty vertex buffer.">vertex_buffer_new</a>( <span class="stringliteral">&quot;v3f:t2f:c4f&quot;</span> ); 

    pen.<a class="code" href="unionvec2.html#a6d28b12b511da692550fc9d37b4e9b1d" title="Alias for second component.">y</a> = -font-&gt;<a class="code" href="structtexture__font__t.html#af310fa623576a8436bff9354f9a5c048" title="The descender is the vertical distance from the horizontal baseline to the lowest &#39;character&#39; coordin...">descender</a>;
    <span class="keywordflow">for</span>( i=0; i&lt;line_count; ++i )
    {
        pen.<a class="code" href="unionvec2.html#a002d3519d48fe3cd79729b5b0ded74bf" title="Alias for first component.">x</a> = 10.0;
        add_text( buffer, font, text, &amp;color, &amp;pen );
        pen.<a class="code" href="unionvec2.html#a6d28b12b511da692550fc9d37b4e9b1d" title="Alias for second component.">y</a> += font-&gt;<a class="code" href="structtexture__font__t.html#a8bd92ddb4c8e456aac6a21f6c268b360" title="This field is simply used to compute a default line spacing (i.e., the baseline-to-baseline distance)...">height</a> - font-&gt;<a class="code" href="structtexture__font__t.html#af40d45f0616a523d97206e6e0e72f421" title="This field is the distance that must be placed between two lines of text.">linegap</a>;
    }

    glClearColor( 1.0, 1.0, 1.0, 1.0 );
    glDisable( GL_DEPTH_TEST ); 
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_BLEND );
    glutMainLoop( );

    <span class="keywordflow">return</span> EXIT_SUCCESS;
}
</pre></div> </div><!-- contents -->
</div>
</body>
</html>
